package com.campus.service.impl;

import com.campus.common.CampusWall;
import com.campus.common.Result;
import com.campus.entity.HotRankings;
import com.campus.entity.PostLikes;
import com.campus.entity.Users;
import com.campus.mapper.HotRankingsMapper;
import com.campus.mapper.PostLikesMapper;
import com.campus.mapper.PostsMapper;
import com.campus.service.HotRankingService;
import com.campus.service.PostLikeService;
import com.campus.utils.SnowFlakeUtil;
import com.campus.utils.TokenUtils;
import io.swagger.v3.oas.models.security.SecurityScheme;
import jakarta.servlet.http.HttpServletRequest;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.Set;

@Service
public class postLikeServiceImpl implements PostLikeService {
    @Autowired
    private TokenUtils tokenUtils;
    @Autowired
    private PostLikesMapper postLikesMapper;
    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    @Autowired
    private HotRankingsMapper hotRankingsMapper;
    @Autowired
    private PostsMapper postsMapper;
    @Autowired
    private HotRankingService hotRankingService;

    /**
     * 统计喜欢人数
     *
     * @param postId
     * @param request
     * @return
     */
    @Override
    public Result likePost(String postId, HttpServletRequest request) {
        Long likeId = SnowFlakeUtil.getId();
        //获取点赞的用户id
        Users currentUser = tokenUtils.getCurrentUser(tokenUtils.getToken(request.getHeader(CampusWall.CAMPUS_TOKEN)));
        PostLikes postLikes = new PostLikes(likeId.toString(), postId, currentUser.getUserId(), null);
        int i = postLikesMapper.likePost(postLikes);
        if (i > 0) {
            Integer allLikesByPostId = postLikesMapper.getAllLikesByPostId(postId);
            if (allLikesByPostId == null) {
                allLikesByPostId = 1;
            }
            //延迟双删
            Set<String> categoryKeys = stringRedisTemplate.keys("category*");
            stringRedisTemplate.delete(categoryKeys);

            // 更新posts表中的点赞数
            postsMapper.updateLikesCount(postId, allLikesByPostId);

//            Set<String> categoryKeys = stringRedisTemplate.keys("category*");
            stringRedisTemplate.delete(categoryKeys);
            //这里点赞成功之后先在热力表里面查询有就把总数更新，没有的话就默认为1
            HotRankings hotRanking = hotRankingsMapper.getHotRankingsByPostId(postId);
            if (hotRanking == null) {
                //获取分类id
                String categoryId = postsMapper.getCategoryIdByPostId(postId);
                //如果为null那么就插入
                HotRankings hotRankings = new HotRankings();
                hotRankings.setRankingId(SnowFlakeUtil.getId().toString());
                hotRankings.setPostId(postId);
                hotRankings.setCategoryId(categoryId);
                hotRankings.setLikesCount(allLikesByPostId);
                // 确保viewsCount不为null
                if (hotRankings.getViewsCount() == null) {
                    hotRankings.setViewsCount(0);
                }
                hotRankings.setHotScore(hotRankings.getLikesCount() * 3 + hotRankings.getViewsCount() * 2);
                int i1 = hotRankingsMapper.insertHotRankingsByLikeCount(hotRankings);
                // 同时更新posts表中的热力值
                postsMapper.updateHotScore(postId, hotRankings.getHotScore());
            } else {
                //这里代表数据库中有数据那么就更新点赞以及分数
                int score = hotRanking.getHotScore() + 3;
                hotRanking.setHotScore(score);
                hotRanking.setLikesCount(allLikesByPostId);
                int i1 = hotRankingsMapper.updateHotRankingsLikeCountByPostId(hotRanking, postId);
                // 同时更新posts表中的热力值
                postsMapper.updateHotScore(postId, hotRanking.getHotScore());
            }

            // 更新Redis ZSet中的分数
            updateHotRankingZSet(postId, allLikesByPostId, hotRanking != null ? hotRanking.getViewsCount() : 0,
                    hotRanking != null ? hotRanking.getCommentsCount() : 0);

            return Result.ok("点赞成功", allLikesByPostId);
            //点赞成功之后要给前端返回当前帖子的总赞数

        }
        return Result.err(Result.CODE_500, "点赞失败");
    }


    /**
     * 取消点赞
     */
    @Override
    public Result unLikePost(String postId, HttpServletRequest request) {
        Users currentUser = tokenUtils.getCurrentUser(tokenUtils.getToken(request.getHeader(CampusWall.CAMPUS_TOKEN)));
        int i = postLikesMapper.deleteByPostAndUserId(postId, currentUser.getUserId());
        if (i > 0) {
            Integer allLikesByPostId = postLikesMapper.getAllLikesByPostId(postId);
            if (allLikesByPostId == null) {
                allLikesByPostId = 0;
            }
            Set<String> categoryKeys = stringRedisTemplate.keys("category*");
            stringRedisTemplate.delete(categoryKeys);
            // 更新posts表中的点赞数
            postsMapper.updateLikesCount(postId, allLikesByPostId);

//            Set<String> categoryKeys = stringRedisTemplate.keys("category*");
            stringRedisTemplate.delete(categoryKeys);
            HotRankings hotRanking = hotRankingsMapper.getHotRankingsByPostId(postId);
            if (hotRanking == null) {
                //获取分类id
                String categoryId = postsMapper.getCategoryIdByPostId(postId);
                //如果为null那么就插入
                HotRankings hotRankings = new HotRankings();
                hotRankings.setRankingId(SnowFlakeUtil.getId().toString());
                hotRankings.setPostId(postId);
                hotRankings.setCategoryId(categoryId);
                hotRankings.setLikesCount(allLikesByPostId);
                // 确保viewsCount不为null
                if (hotRankings.getViewsCount() == null) {
                    hotRankings.setViewsCount(0);
                }
                hotRankings.setHotScore(hotRankings.getLikesCount() * 3 + hotRankings.getViewsCount() * 2);
                int i1 = hotRankingsMapper.insertHotRankingsByLikeCount(hotRankings);
                // 同时更新posts表中的热力值
                postsMapper.updateHotScore(postId, hotRankings.getHotScore());
            } else {
                //这里代表数据库中有数据那么就更新点赞以及分数
                int score = hotRanking.getHotScore() - 3;
                hotRanking.setHotScore(score);
                hotRanking.setLikesCount(allLikesByPostId);
                int i1 = hotRankingsMapper.updateHotRankingsLikeCountByPostId(hotRanking, postId);
                // 同时更新posts表中的热力值
                postsMapper.updateHotScore(postId, hotRanking.getHotScore());
            }

            // 更新Redis ZSet中的分数
            updateHotRankingZSet(postId, allLikesByPostId, hotRanking != null ? hotRanking.getViewsCount() : 0,
                    hotRanking != null ? hotRanking.getCommentsCount() : 0);

            return Result.ok("取消点赞成功", allLikesByPostId);
        }
        return Result.err(Result.CODE_500, "取消点赞失败");
    }

    /**
     * 校验用户是否点赞
     *
     * @param postId
     * @param request
     * @return
     */
    @Override
    public Result checkLike(String postId, HttpServletRequest request) {
        Users currentUser = tokenUtils.getCurrentUser(tokenUtils.getToken(request.getHeader(CampusWall.CAMPUS_TOKEN)));
        int i = postLikesMapper.checkLike(postId, currentUser.getUserId());
        if (i > 0) {
            return Result.ok(1);
        }
        return Result.ok(0);
    }

    /**
     * 更新热力榜ZSet中的分数
     *
     * @param postId        帖子ID
     * @param likesCount    点赞数
     * @param viewsCount    浏览量
     * @param commentsCount 评论数
     */
    private void updateHotRankingZSet(String postId, int likesCount, int viewsCount, int commentsCount) {
        // 更新今天、本周、本月的热力榜
        ((HotRankingServiceImpl) hotRankingService).updatePostScoreInZSet(postId, likesCount, viewsCount, commentsCount, "today");
        ((HotRankingServiceImpl) hotRankingService).updatePostScoreInZSet(postId, likesCount, viewsCount, commentsCount, "week");
        ((HotRankingServiceImpl) hotRankingService).updatePostScoreInZSet(postId, likesCount, viewsCount, commentsCount, "month");
    }

}